package framework.attack;

import java.awt.geom.Rectangle2D;

import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.Sound;
import org.newdawn.slick.geom.Rectangle;
import framework.BasicEntity;
import framework.BasicFighter;
import framework.C;
import framework.Util;
import framework.collision.AttackCollisionManager;
import framework.collision.SimpleAttackCollisionManager;

public class BasicAttack<T extends BasicFighter> extends BasicEntity implements Attack<T> {

	protected int currentTime;

	protected T attacker;

	private AttackCollisionManager collision;

	protected boolean hasHit;

	protected Sound hitSound;

	protected Sound parrySound;

	public BasicAttack() {
		this(null);
	}

	public BasicAttack(T attacker) {
		this.currentTime = 0;
		this.attacker = attacker;
		this.collision = new SimpleAttackCollisionManager();
		this.hasHit = false;
		try {
			this.hitSound = new Sound(C.ASSETS_FOLDER + "hit.ogg");
			this.parrySound = new Sound(C.ASSETS_FOLDER + "parry.ogg");
		} catch (SlickException e) {
			e.printStackTrace();
		}
	}

	public void init(GameContainer gc) {
		setScale(Util.getScale(gc));
	}

	@Override
	public int getPower() {
		return 10;
	}

	@Override
	public void trigger() {
		hasHit = false;
		currentTime = 1;
		collision.addAttack(this);
	}

	@Override
	public void update(GameContainer gc, int delta) {
		if(isActive()) {
			this.currentTime += delta;
			this.collision.update(gc, delta);
		} else {
			this.collision.removeAttack(this);
			this.hasHit = false;
		}
	}

	public boolean isInBound(GameContainer gc) {
		return getHitBox().getX() > 0 && getHitBox().getY() > 0 &&
				getHitBox().getX() + getHitBox().getWidth() < gc.getWidth() &&
				getHitBox().getY() + getHitBox().getHeight() < gc.getHeight();
	}

	public boolean hasHit() {
		return hasHit;
	}

	@Override
	public void draw(Graphics g) {
	}

	public void interrupt() {
		this.currentTime = 0;
		this.collision.removeAttack(this);
		getAttacker().interruptJump();
	}

	@Override
	public int getDuration() {
		return 400;
	}

	@Override
	public boolean isActive() {
		return this.currentTime > 0 &&  this.currentTime < getDuration();
	}

	@Override
	public T getAttacker() {
		return this.attacker;
	}

	@Override
	public Rectangle getHitBox() {
		return null;
	}

	public void setAttackCollisionManager(AttackCollisionManager manager) {
		this.collision = manager;
	}

	@Override
	public void setAttacker(T f) {
		this.attacker = f;	
	}

	@Override
	public boolean isBlocking() {
		return false;
	}

	@Override
	public boolean isDrawingAttacker() {
		return false;
	}

	@Override
	public void onHit(BasicFighter f) {
		if (f.isAttacking() && f.getCurrentAttack().isInterruptable()) {
			f.getCurrentAttack().interrupt();
		}
		if (!hasHit) {
			if (f.isParrying()) {
				f.parry(getPower());
				this.parrySound.play();
			} else {
				f.hit(getPower());
				this.hitSound.play();
			}
		}
		hasHit = true;
	}

	public void onHit(BasicFighter f, Rectangle2D Collision) {
		onHit(f);
	}
	
	public boolean collidesOnAttack() {
		return false;
	}
	
	public void onRelease() {
		
	}

	@Override
	public boolean isInterruptable() {
		return isActive();
	}
}
